package flex.cc.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import flex.cc.PublicUtil;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;


/**
 *
 * @author WANGCONG
 * 2021年9月16日下午4:22:39
 * @desc orderNo主键生成规则工具类
 */
@Component
@Slf4j
@PropertySource("classpath:application.yml")
public class OrderNoGenerateUtil {

	private static String param = "ZX";
	
	private static String dj_param = "ZXDJ";
	
	private static String package_param = "ZXHYFWB";

	@Value("${spring.datasource.driver-class-name}")
	private String diverClassName;


	@Value("${spring.datasource.url}")
	private String url;

	@Value("${spring.datasource.username}")
	private String username;

	@Value("${spring.datasource.password}")
	private String password;

	/**
	 * @description 获取服务单号，即服务单唯一编号，规则：ZX+年月日（两位年两位月两位日）+渠道方编码+顺序编码（四位，不足补0，每日从0000开始）
	 * @param sourceCode 渠道方编号
	 * @return
	 * @author wkangle
	 * @time 2021/09/17 0017 12:02
	 * @exception/throws
	*/
	public String getOrderNo(String sourceCode) {
		String orderNoNum = this.getOrderNoNum(param, sourceCode);
		if (orderNoNum != null) {
			StringBuffer orderNo = new StringBuffer("");
			orderNo.append(param).
					append(new SimpleDateFormat("yyyyMMdd").format(new Date()).substring(2, 8)).
					append(sourceCode).append(orderNoNum);
			return orderNo.toString();
		}
		return null;
	}
	
	/**
	 *
	 * @author WANGCONG
	 * 2022年1月19日下午17:01:52
	 * @desc 代驾服务单号生成
	 */
	public String getDriverOrderNo(String sourceCode) {
		String orderNoNum = this.getOrderNoNum(dj_param, sourceCode);
		if (orderNoNum != null) {
			StringBuffer orderNo = new StringBuffer("");
			orderNo.append(dj_param).
					append(new SimpleDateFormat("yyyyMMdd").format(new Date()).substring(2, 8)).
					append(sourceCode).append(orderNoNum);
			return orderNo.toString();
		}
		return null;
	}

	/**
	 * @description 从数据库sequence表中获取orderNoNum值，四位，不足补0，每日从0000开始
	 * @param param 开头标识符
	 * @return
	 * @author wkangle
	 * @time 2021/09/17 0017 11:59
	 * @exception/throws
	*/
	private String getOrderNoNum(String param, String sourceCode) {
		String orderNoNum = null;
		try {
			Class.forName(diverClassName);//用反射的方式将驱动包加载到内存中
			Connection conn = DriverManager.getConnection(url,username,password);

			PreparedStatement pstat = conn.prepareStatement("select seq(?, ?) as res");
			pstat.setString(1,param);
			pstat.setString(2, sourceCode);
			ResultSet rs = pstat.executeQuery();
			while (rs.next()){
				orderNoNum = rs.getString(1);
			}

			conn.close();
		} catch (Exception e) {
			log.error("OrderNoGenerateUtil.getOrderNo() ==> 获取服务单号异常", e.getStackTrace());
			e.printStackTrace();
		}
		return orderNoNum;
	}

	static public String genOrderNo(){
		return "ZX" + getYMDHMSS() + "01" + leftAppendChr(""+genNextConsultSeq(),4,"0");
	}

	private static long _orderNoSequenceCounter = 0;
	static synchronized private long genNextConsultSeq(){
		_orderNoSequenceCounter++;
		if( _orderNoSequenceCounter>=9999 ){
			_orderNoSequenceCounter=0;
		}
		return _orderNoSequenceCounter;
	}
	
	/**
	 * @description 从数据库t_store_package_config表中获取最大config_code值 切割转换类型 +1 补0
	 * @return
	 * @author R
	 * @time 2022年03月01日 15:20:11
	 * @exception/throws
	*/
	public String getPackageConfigCode() {
		String configCode = null;
		try {
			Class.forName(diverClassName);//用反射的方式将驱动包加载到内存中
			Connection conn = DriverManager.getConnection(url,username,password);
			PreparedStatement pstat = conn.prepareStatement("select config_code from t_store_package_config order by config_code desc limit 1");
			ResultSet rs = pstat.executeQuery();
			String maxConfigCode = "";
			while (rs.next()){
				maxConfigCode = rs.getString(1);
			}
			if(PublicUtil.isNotEmpty(maxConfigCode)){
				int code = Integer.parseInt(maxConfigCode.substring(7));
				configCode = package_param+leftAppendChr(""+(code+1),9,"0");
			}
			conn.close();
		} catch (Exception e) {
			log.error("OrderNoGenerateUtil.getPackageConfigCode() ==> 获取服务包配置编码异常", e.getStackTrace());
			e.printStackTrace();
		}
		return configCode;
	}
	
	public static String getYMDHMSS(){
		String strYMDHMSS = "";
		Date currentDateTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");
		strYMDHMSS = formatter.format(currentDateTime);
		return strYMDHMSS;
	}

	static private String leftAppendChr(String s,int length,String chr ){
		if( s == null ){
			s="";
		}
		if( s.length() >length ){
			return s.substring(0,length);
		}
		while( s.length() < length ){
			s = chr+s;
		}
		return s;
	}
    public String generateBusinessNo(String sequencename) {
    	String orderNoNum = null;
		try {
			Class.forName(diverClassName);//用反射的方式将驱动包加载到内存中
			Connection conn = DriverManager.getConnection(url,username,password);

			PreparedStatement pstat = conn.prepareStatement("SELECT NEXTVAL(?) from DUAL");
			pstat.setString(1,sequencename);
			ResultSet rs = pstat.executeQuery();
			while (rs.next()){
				orderNoNum = rs.getString(1);
				orderNoNum = leftAppendChr(orderNoNum,2,"0");
			}
			conn.close();
		} catch (Exception e) {
			log.error("OrderNoGenerateUtil.generateBusinessNo() ==> 获取服务单号异常", e.getStackTrace());
			e.printStackTrace();
		}
		return orderNoNum;
    }
    public String resetSequenceByName(String sequencename) {
    	String orderNoNum = null;
		try {
			Class.forName(diverClassName);//用反射的方式将驱动包加载到内存中
			Connection conn = DriverManager.getConnection(url,username,password);

			PreparedStatement pstat = conn.prepareStatement("select setval(?,'1') from DUAL");
			pstat.setString(1,sequencename);
			ResultSet rs = pstat.executeQuery();
			while (rs.next()){
				orderNoNum = rs.getString(1);
				orderNoNum = leftAppendChr(orderNoNum,2,"0");
			}
			conn.close();
		} catch (Exception e) {
			log.error("OrderNoGenerateUtil.resetSequenceByName() ==> 获取服务单号异常", e.getStackTrace());
			e.printStackTrace();
		}
		return orderNoNum;
    }
    public void updateSequenceTimeByName(String sequencename) {
    	String orderNoNum = null;
		try {
			Class.forName(diverClassName);//用反射的方式将驱动包加载到内存中
			Connection conn = DriverManager.getConnection(url,username,password);

			PreparedStatement pstat = conn.prepareStatement("update sequence set years =now()  where seq_name = ?");
			pstat.setString(1,sequencename);
			pstat.executeUpdate();
			conn.close();
		} catch (Exception e) {
			log.error("OrderNoGenerateUtil.updateSequenceTimeByName() ==> 获取服务单号异常", e.getStackTrace());
			e.printStackTrace();
		}
    }
	public String getDiverClassName() {
		return diverClassName;
	}

	public void setDiverClassName(String diverClassName) {
		this.diverClassName = diverClassName;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}
